﻿using System;
using System.Web;
using KeanuMvc.Reference;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

namespace KeanuMvc.Reference {

    public class Images {

        #region Fields
        private Regex _nameValidationExpression = new Regex(@"[^\w/]");
        private int _thumbnailSize = 150;
        private string folderPath = string.Empty;
        #endregion

        public Images(string ImageVirtualFolderPath) {
            folderPath = ImageVirtualFolderPath;
        }

        public void ViewThumbnail() {
            GenerateImage(150);
        }

        private void GenerateImage(int NewSize) {
            try {
                _thumbnailSize = Convert.ToInt32(HttpContext.Current.Request["s"].ToString());
            } catch { }
            string photoName = HttpContext.Current.Request["f"].Split('.')[0];
            //if (_nameValidationExpression.IsMatch(photoName)) {
            //    throw new HttpException(404, "Invalid photo name.");
            //}
            string cachePath = Path.Combine(HttpRuntime.CodegenDir, photoName + "_" + _thumbnailSize + "." + HttpContext.Current.Request["f"].Split('.')[1]);
            if (File.Exists(cachePath)) {
                OutputCacheResponse(File.GetLastWriteTime(cachePath));
                HttpContext.Current.Response.WriteFile(cachePath);
                return;
            }
            string photoPath = HttpContext.Current.Server.MapPath(folderPath + HttpContext.Current.Request["f"]);
            Bitmap photo;
            try {
                photo = new Bitmap(photoPath);
            } catch (ArgumentException) {
                throw new HttpException(404, "Photo not found.");
            }
            HttpContext.Current.Response.ContentType = "image/png";
            int width, height;
            if (photo.Width > photo.Height) {
                width = _thumbnailSize;
                height = photo.Height * _thumbnailSize / photo.Width;
            } else {
                width = photo.Width * _thumbnailSize / photo.Height;
                height = _thumbnailSize;
            }
            Bitmap target = new Bitmap(width, height);
            using (Graphics graphics = Graphics.FromImage(target)) {
                graphics.CompositingQuality = CompositingQuality.HighSpeed;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.CompositingMode = CompositingMode.SourceCopy;
                graphics.DrawImage(photo, 0, 0, width, height);
                using (MemoryStream memoryStream = new MemoryStream()) {
                    target.Save(memoryStream, ImageFormat.Png);
                    OutputCacheResponse(File.GetLastWriteTime(photoPath));
                    using (FileStream diskCacheStream = new FileStream(cachePath, FileMode.CreateNew)) {
                        memoryStream.WriteTo(diskCacheStream);
                    }
                    memoryStream.WriteTo(HttpContext.Current.Response.OutputStream);
                }
            }
        }

        private void OutputCacheResponse(DateTime lastModified) {
            HttpCachePolicy cachePolicy = HttpContext.Current.Response.Cache;
            cachePolicy.SetCacheability(HttpCacheability.Public);
            cachePolicy.VaryByParams["f"] = true;
            cachePolicy.VaryByParams["s"] = true;
            cachePolicy.SetOmitVaryStar(true);
            cachePolicy.SetExpires(DateTime.Now + TimeSpan.FromDays(365));
            cachePolicy.SetValidUntilExpires(true);
            cachePolicy.SetLastModified(lastModified);
        }


    }

}